﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Globalization;
using VDS.RDF;
using VDS.RDF.Ontology;
using VDS.RDF.Configuration;

namespace FotoAnotSharp
{
    /// <summary>
    /// This class load nodes from file (gate.owl.xml) and create object hierarchy
    /// Using dotNetRDF Library
    /// </summary>
    class GateReader
    {
        private static readonly Uri C_OWL = new Uri("http://www.w3.org/2002/07/owl"); //TODO LOAD FROM FILE
        private static readonly Uri C_GATE = new Uri("http://www.fi.muni.cz/~oslejsek/GATE/gate.owl");
        private static readonly Uri C_RDFS = new Uri("http://www.w3.org/2000/01/rdf-schema");
        private static readonly Uri C_RDF = new Uri("http://www.w3.org/1999/02/22-rdf-syntax-ns");
        public static string C_PARENT_OBJECT = "GraphicalObject";


        public GateReader()
        { 
        
        }

        /// <summary>
        /// load nodes from file and make hierarchy
        /// </summary>
        /// <param name="file">file with nodes</param>
        /// <param name="hiearchy">final hierarchy</param>
        public void Load(string file, out GraphicalObjectHiearchy hiearchy)
        {
            Graph gr = new Graph();
            gr.LoadFromFile(file);

            hiearchy = new GraphicalObjectHiearchy();
            hiearchy.Parent = hiearchy.CreatObject(C_PARENT_OBJECT);

            //build hieararchy
            Queue<GraphicalObject> nodes = new Queue<GraphicalObject>();
            nodes.Enqueue(hiearchy.Parent);
            while (nodes.Count > 0)
            {
                GraphicalObject parent = nodes.Dequeue();
                
                foreach (Triple tr in gr.GetTriplesWithObject(new Uri(C_GATE, parent.FragmentName))
                    .Where(t => t.Subject is UriNode && t.Predicate is UriNode 
                        && (t.Predicate as UriNode).Uri.Fragment == "#subClassOf"))
                {
                    UriNode subj = tr.Subject as UriNode;
                    string name = subj.Uri.Fragment.Substring(1); //remove sharp
                    
                    GraphicalObject anc = null;
                    if (hiearchy.TryGetObject(name, out anc))
                        continue;

                    anc = hiearchy.CreatObject(name);
                    Trace.WriteLine(anc);
                    parent.AddAncestor(anc);
                    nodes.Enqueue(anc);
                }
            }

            foreach (Triple tr in gr.GetTriplesWithPredicate(new Uri(C_RDFS, "#comment")).Where(t => t.Subject is UriNode && t.Object is LiteralNode))
            {
                LiteralNode comment = tr.Object as LiteralNode;
                GraphicalObject obj;
                if (!hiearchy.TryGetObject((tr.Subject as UriNode).Uri.Fragment.Substring(1), out obj))
                    continue;

                obj.AddComment(CultureInfo.GetCultureInfo(comment.Language), comment.Value);

            }

            foreach (Triple tr in gr.GetTriplesWithPredicate(new Uri(C_OWL, "#equivalentClass"))
                .Where(t => t.Subject is UriNode && t.Object is UriNode))
            {                
                GraphicalObject obj;
                if (!hiearchy.TryGetObject((tr.Subject as UriNode).Uri.Fragment.Substring(1), out obj))
                    continue;
                hiearchy.AddObjectAllias(obj, (tr.Object as UriNode).Uri.Fragment.Substring(1));
            }

            /*foreach (Triple tr in gr.Triples)
            {
                Console.WriteLine(tr.Object);
                Console.WriteLine((tr.Predicate));
                Console.WriteLine(tr.Subject);
                Console.ReadLine();
            }*/
        }
    }
}
